package com.chushouya.order.rabbitmq.listener;

import com.chushouya.common.dto.QueueMessage;
import com.chushouya.order.constants.OrderTypeEnum;
import com.chushouya.order.dao.entity.OrderEntity;
import com.chushouya.order.dao.repository.OrderRepository;
import com.general.framework.core.exception.ViolationException;
import com.chushouya.order.dto.admin.action.OrderDeliverAction;
import com.chushouya.order.service.admin.KefuOrderActionService;
import com.chushouya.order.service.common.OrderExpressService;
import com.general.framework.core.lang.Strings;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * 快递预约消息监听器
 * 
 * @author chushouya
 */
@Component
@Slf4j
public class ExpressReservationMessageListener {

    @Resource
    private KefuOrderActionService kefuOrderActionService;
    
    @Resource
    private OrderExpressService orderExpressService;

    @Resource
    private OrderRepository orderRepository;

    /**
     * 处理快递预约消息
     * 
     * @param queueMessage 队列消息对象
     */
    @RabbitListener(queuesToDeclare = @Queue(name = "chushouya.express.reservation", durable = "true"))
    public void handleExpressReservationMessage(QueueMessage<?> queueMessage) {
        log.info("接收到快递预约消息: messageId={}, data={}", queueMessage.getMessageId(), queueMessage.getData());
        
        try {
            // 获取订单ID
            Object data = queueMessage.getData();
            if (data == null) {
                log.error("快递预约消息数据为空: messageId={}", queueMessage.getMessageId());
                log.warn("数据为空的消息已处理，避免重复处理: messageId={}", queueMessage.getMessageId());
                return;
            }
            
            Long orderId;
            try {
                if (data instanceof Long) {
                    orderId = (Long) data;
                } else if (data instanceof Integer) {
                    orderId = ((Integer) data).longValue();
                } else if (data instanceof String) {
                    orderId = Long.valueOf(data.toString());
                } else {
                    log.error("快递预约消息数据类型不支持: messageId={}, dataType={}", 
                            queueMessage.getMessageId(), data.getClass().getSimpleName());
                    log.warn("不支持的数据类型消息已处理，避免重复处理: messageId={}", queueMessage.getMessageId());
                    return;
                }
                
                // 验证订单ID有效性
                if (orderId == null || orderId <= 0) {
                    log.error("订单ID无效: orderId={}, messageId={}", orderId, queueMessage.getMessageId());
                    log.warn("无效订单ID消息已处理，避免重复处理: messageId={}", queueMessage.getMessageId());
                    return;
                }
            } catch (NumberFormatException e) {
                log.error("订单ID格式转换失败: data={}, messageId={}, error={}", 
                        data, queueMessage.getMessageId(), e.getMessage());
                log.warn("格式转换失败消息已处理，避免重复处理: messageId={}", queueMessage.getMessageId());
                return;
            }
            // 验证订单金额是否满足快递预约条件
            if (!validateOrderExpress(orderId)) {
                log.info("订单不满足快递预约条件，跳过快递预约，订单ID: {}", orderId);
                return;
            }
            log.info("开始处理快递预约，订单ID: {}, messageId: {}", orderId, queueMessage.getMessageId());
            
            // 创建订单退货操作对象
            OrderDeliverAction orderDeliverAction = new OrderDeliverAction();
            orderDeliverAction.setOrderId(orderId);
            orderDeliverAction.setActionNote("系统自动预约快递");
            
            // 调用订单退货方法
            kefuOrderActionService.orderDeliver(orderDeliverAction);
            
            log.info("快递预约处理完成，订单ID: {}, messageId: {}", orderId, queueMessage.getMessageId());
            
        } catch (ViolationException e) {
            log.error("快递预约消息验证错误: {}, messageId: {}, data: {}",
                    e.getMessage(), queueMessage.getMessageId(), queueMessage.getData());
            // 验证异常不抛出，避免消息重新入队
            log.warn("验证异常消息已处理，避免重复处理: messageId={}", queueMessage.getMessageId());
        } catch (Exception e) {
            log.error("处理快递预约消息异常: {}, messageId: {}, data: {}", 
                    e.getMessage(), queueMessage.getMessageId(), queueMessage.getData(), e);
            // 处理异常不抛出，避免消息重新入队
            log.warn("处理异常消息已处理，避免重复处理: messageId={}", queueMessage.getMessageId());
        }
    }

    /**
     * 处理快递取消消息
     * 
     * @param queueMessage 队列消息对象
     */
    @RabbitListener(queuesToDeclare = @Queue(name = "chushouya.express.cancel", durable = "true"))
    public void handleExpressCancelMessage(QueueMessage<?> queueMessage) {
        log.info("接收到快递取消消息: messageId={}, data={}", queueMessage.getMessageId(), queueMessage.getData());
        
        try {
            // 获取订单ID
            Object data = queueMessage.getData();
            if (data == null) {
                log.error("快递取消消息数据为空: messageId={}", queueMessage.getMessageId());
                log.warn("数据为空的消息已处理，避免重复处理: messageId={}", queueMessage.getMessageId());
                return;
            }

            Long orderId;
            try {
                if (data instanceof Long) {
                    orderId = (Long) data;
                } else if (data instanceof Integer) {
                    orderId = ((Integer) data).longValue();
                } else if (data instanceof String) {
                    orderId = Long.valueOf(data.toString());
                } else {
                    log.error("快递预约消息数据类型不支持: messageId={}, dataType={}",
                            queueMessage.getMessageId(), data.getClass().getSimpleName());
                    log.warn("不支持的数据类型消息已处理，避免重复处理: messageId={}", queueMessage.getMessageId());
                    return;
                }

                // 验证订单ID有效性
                if (orderId == null || orderId <= 0) {
                    log.error("订单ID无效: orderId={}, messageId={}", orderId, queueMessage.getMessageId());
                    log.warn("无效订单ID消息已处理，避免重复处理: messageId={}", queueMessage.getMessageId());
                    return;
                }
            } catch (NumberFormatException e) {
                log.error("订单ID格式转换失败: data={}, messageId={}, error={}",
                        data, queueMessage.getMessageId(), e.getMessage());
                log.warn("格式转换失败消息已处理，避免重复处理: messageId={}", queueMessage.getMessageId());
                return;
            }
            
            log.info("开始处理快递取消，订单ID: {}, messageId: {}", orderId, queueMessage.getMessageId());

            orderExpressService.cancelExpress(orderId);

            log.info("快递取消消息处理完成，订单ID: {}, messageId: {}", orderId, queueMessage.getMessageId());
            
        } catch (ViolationException e) {
            log.error("快递取消消息验证错误: {}, messageId: {}, data: {}",
                    e.getMessage(), queueMessage.getMessageId(), queueMessage.getData());
            // 验证异常不抛出，避免消息重新入队
            log.warn("验证异常消息已处理，避免重复处理: messageId={}", queueMessage.getMessageId());
        } catch (Exception e) {
            log.error("处理快递取消消息异常: {}, messageId: {}, data: {}", 
                    e.getMessage(), queueMessage.getMessageId(), queueMessage.getData(), e);
            // 处理异常不抛出，避免消息重新入队
            log.warn("处理异常消息已处理，避免重复处理: messageId={}", queueMessage.getMessageId());
        }
    }

    /**
     * 验证快递预约条件
     */
    private boolean validateOrderExpress(Long orderId) {
        final OrderEntity orderInfo = orderRepository.selectByPrimaryKey(orderId);
        if (Objects.isNull(orderInfo)) {
            log.error("订单不存在，无法进行快递预约，订单ID: {}", orderId);
            return false;
        }
        try {
            // 1. 判断是否有合作商订单号，如果有则不进行快递预约
            if (Strings.isNotBlank(orderInfo.getPartnerOrderNo())) {
                log.info("订单存在合作商订单号，跳过快递预约，订单ID: {}, 合作商订单号: {}",
                        orderInfo.getOrderId(), orderInfo.getPartnerOrderNo());
                return false;
            }

            // 2. 判断订单类型是否为2（上门回收），如果是则不进行快递预约
            if (orderInfo.getOrderType().equals(OrderTypeEnum.DOOR_RECYCLE.value())) {
                log.info("订单类型为上门回收，跳过快递预约，订单ID: {}, 订单类型: {}",
                        orderInfo.getOrderId(), orderInfo.getOrderType());
                return false;
            }
            return true;

        } catch (Exception e) {
            log.error("验证订单金额异常，订单ID: {}, 错误信息: {}", orderInfo.getOrderId(), e.getMessage(), e);
            // 异常情况下默认不进行快递预约
            return false;
        }
    }
}
